package com.syg.apiversion;

import com.alibaba.fastjson.JSONObject;
import com.syg.boot.util.text.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StreamUtils;
import org.springframework.web.servlet.mvc.condition.RequestCondition;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.regex.Pattern;

public class ApiVersionRequestCondition implements RequestCondition<ApiVersionRequestCondition> {
    private static final Logger log = LoggerFactory.getLogger(ApiVersionRequestCondition.class);
    private static final Pattern VERSION_PREFIX_PATTERN = Pattern.compile("/v(\\d+)/");
    private static final String MULTIPART_CONTENT_TYPE = "multipart/form-data";
    private static final String URLENCODED_CONTENT_TYPE = "x-www-form-urlencoded";
    private static final String REQUEST_CHARSET = "UTF-8";
    private static final String VERSION_KEY = "version";
    private String apiVersion;

    ApiVersionRequestCondition(String apiVersion) {
        this.apiVersion = apiVersion;
    }

    @Override
    public ApiVersionRequestCondition combine(ApiVersionRequestCondition other) {
        return new ApiVersionRequestCondition(other.getApiVersion());
    }

    @Override
    public ApiVersionRequestCondition getMatchingCondition(HttpServletRequest request) {
        String requestContent = this.getRequestContent(request);
        if (StringUtil.isEmpty(requestContent)) {
            return null;
        } else {
            String requestVersion = this.getRequestVersion(requestContent);
            if (StringUtil.isEmpty(requestVersion)) {
                return null;
            } else {
                return requestVersion.equals(this.getApiVersion()) ? this : null;
            }
        }
    }

    @Override
    public int compareTo(ApiVersionRequestCondition other, HttpServletRequest request) {
        return this.getApiVersion().compareTo(other.getApiVersion());
    }

    private String getRequestVersion(String requestContent) {
        JSONObject jsonObject = JSONObject.parseObject(requestContent);
        return jsonObject.getString("version");
    }

    private String getRequestContent(HttpServletRequest request) {
        String contentType = request.getContentType();
        if (StringUtil.isNotEmpty(contentType) && (contentType.contains("multipart/form-data") || contentType.contains("x-www-form-urlencoded"))) {
            return null;
        } else {
            String bodyString = null;

            try {
                byte[] byteArray = StreamUtils.copyToByteArray(request.getInputStream());
                bodyString = new String(byteArray, "UTF-8");
            } catch (IOException var5) {
                log.error("api版本匹配获取请求报文内容发生Exception:", var5.getMessage());
            }

            return bodyString;
        }
    }

    public String getApiVersion() {
        return this.apiVersion;
    }

    public void setApiVersion(String apiVersion) {
        this.apiVersion = apiVersion;
    }

    @Override
    public boolean equals(Object o) {
        if (o == this) {
            return true;
        } else if (!(o instanceof ApiVersionRequestCondition)) {
            return false;
        } else {
            ApiVersionRequestCondition other = (ApiVersionRequestCondition)o;
            if (!other.canEqual(this)) {
                return false;
            } else {
                Object this$apiVersion = this.getApiVersion();
                Object other$apiVersion = other.getApiVersion();
                if (this$apiVersion == null) {
                    if (other$apiVersion != null) {
                        return false;
                    }
                } else if (!this$apiVersion.equals(other$apiVersion)) {
                    return false;
                }

                return true;
            }
        }
    }

    protected boolean canEqual(Object other) {
        return other instanceof ApiVersionRequestCondition;
    }

    @Override
    public int hashCode() {
        int result = 1;
        Object $apiVersion = this.getApiVersion();
        result = result * 59 + ($apiVersion == null ? 43 : $apiVersion.hashCode());
        return result;
    }

    @Override
    public String toString() {
        return "ApiVersionRequestCondition(apiVersion=" + this.getApiVersion() + ")";
    }
}
